package com.jiyi.easemob.util;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.litepal.crud.DataSupport;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Log;
import android.util.LruCache;
import android.util.Pair;

import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMConversation;
import com.jiyi.easemob.bean.EasemobUser;

@SuppressLint("NewApi")
public class EaseCacheUtil {

	/**
	 * 缓存聊天用户的类，当存储用户的大小大于LruCache设定的值，系统自动释放内存
	 */
	private LruCache<String, EasemobUser> mMemoryCache;

	private static EaseCacheUtil instance = null;

	public synchronized static EaseCacheUtil getInstance() {
		if (instance == null) {
			instance = new EaseCacheUtil();
		}
		return instance;
	}

	public void init() {
		// 获取系统分配给每个应用程序的最大内存，每个应用系统分配1/16
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int mCacheSize = maxMemory / 16;
		// 给LruCache分配1/16
		mMemoryCache = new LruCache<String, EasemobUser>(mCacheSize) {
		};
	}

	/**
	 * 添加环信用户到内存缓存
	 * 
	 * @param key
	 * @param EasemobUser
	 */
	public void addEasemobUserToMemoryCache(String key, EasemobUser easemobUser) {
		if (getEasemobUserFromMemCache(key) == null && easemobUser != null) {
			mMemoryCache.put(key, easemobUser);
		}
	}

	/**
	 * 从内存缓存中获取一个环信用户
	 * 
	 * @param key
	 * @return
	 */
	public EasemobUser getEasemobUserFromMemCache(String key) {
		return mMemoryCache.get(key);
	}
	
	/**
	 * author hym
	 * desc 从内存缓存中移除一个环信用户
	 * 2016-7-29
	 * @param key
	 */
	public void removeEasemobUser(String key)
	{
		mMemoryCache.remove(key);
	}

	/**
	 * 从数据库中获取环信用户
	 * 
	 * @param url
	 * @return
	 */
	private EasemobUser getEaseMobUserFromDb(String username) {
		EasemobUser easemobUser = null;
		easemobUser = DataSupport.where("easeUid = ?", username).findFirst(
				EasemobUser.class);
		if (null != easemobUser) {
			addEasemobUserToMemoryCache(username, easemobUser);
		}
		return easemobUser;
	}

	/**
	 * author hym desc 对外获取环信用户接口，先从缓存，没有再到数据库 2016-7-29
	 * 
	 * @param username
	 */
	public EasemobUser getEaseMobUser(String username) {
		if (TextUtils.isEmpty(username)) {
			//throw new NullPointerException("不能查找空的环信用户名");
			Log.e("ease ", "不能查找空的环信用户名");
			return null;
		}
		if (getEasemobUserFromMemCache(username) != null) {
			return getEasemobUserFromMemCache(username);
		} else {
			return getEaseMobUserFromDb(username);
		}

	}

	/**
	 * author hym
	 * desc 保存环信用户，如果信息有变动的情况
	 * 2016-7-29
	 * @param nickName
	 * @param avatar
	 * @param memberId
	 * @param easeUid
	 */
	public synchronized void saveEaseMobUser(String nickName, String avatar,
			String memberId, String easeUid) {
		// 保存自身的昵称和头像到数据库
		EasemobUser easemobUser = EaseCacheUtil.getInstance().getEaseMobUser(
				easeUid);
		if (null == easemobUser) {
			easemobUser = new EasemobUser();
			easemobUser.setAvatar(avatar);
			easemobUser.setNickName(nickName);
			easemobUser.setEaseUid(easeUid);
			easemobUser.setMemberId(memberId);
			easemobUser.save();
			//新增用户到缓存
			addEasemobUserToMemoryCache(easeUid, easemobUser);
			
		} else {
			// 老用户有数据变动保存
			if (!nickName.equals(easemobUser.getNickName())
					|| !avatar.equals(easemobUser.getAvatar())
					|| !memberId.equals(easemobUser.getMemberId())) {
				easemobUser.setAvatar(avatar);
				easemobUser.setNickName(nickName);
				easemobUser.setEaseUid(easeUid);
				easemobUser.setMemberId(memberId);
				// 设置好接收到的用户属性后保存
				easemobUser.save();
				//移除之前的用户缓存
				removeEasemobUser(easeUid);
				//新增用户缓存
				addEasemobUserToMemoryCache(easeUid, easemobUser);
			}
		}
		
	}
	
	
	
	/**
	 * 从环信sdk里面获取聊天列表
	 * */
    public  List<EMConversation> loadConversationList(){
        // get all conversations
        Map<String, EMConversation> conversations = EMClient.getInstance().chatManager().getAllConversations();
        List<Pair<Long, EMConversation>> sortList = new ArrayList<Pair<Long, EMConversation>>();
        /**
         * lastMsgTime will change if there is new message during sorting
         * so use synchronized to make sure timestamp of last message won't change.
         */
        synchronized (conversations) {
            for (EMConversation conversation : conversations.values()) {
                if (conversation.getAllMessages().size() != 0) {
                    sortList.add(new Pair<Long, EMConversation>(conversation.getLastMessage().getMsgTime(), conversation));
                }
            }
        }
        try {
            // Internal is TimSort algorithm, has bug
            sortConversationByLastChatTime(sortList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<EMConversation> list = new ArrayList<EMConversation>();
        for (Pair<Long, EMConversation> sortItem : sortList) {
            list.add(sortItem.second);
        }
        return list;
    }
    
    /**
     * sort conversations according time stamp of last message
     * 
     * @param conversationList
     */
    private  void sortConversationByLastChatTime(List<Pair<Long, EMConversation>> conversationList) {
        Collections.sort(conversationList, new Comparator<Pair<Long, EMConversation>>() {
            @Override
            public int compare(final Pair<Long, EMConversation> con1, final Pair<Long, EMConversation> con2) {

                if (con1.first == con2.first) {
                    return 0;
                } else if (con2.first > con1.first) {
                    return 1;
                } else {
                    return -1;
                }
            }

        });
    }
	
}
